package com.youpingou.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youpingou.client.WebServiceClient;
import com.youpingou.domain.Address;
import com.youpingou.domain.Cart;
import com.youpingou.domain.Order;
import com.youpingou.domain.OrderGoods;
import com.youpingou.mapper.OrderGoodsMapper;
import com.youpingou.mapper.OrderMapper;
import com.youpingou.service.OrderService;
import com.youpingou.util.IdWorker;
import com.youpingou.util.JWTUtil;
import com.youpingou.vo.OrderRequest;
import io.jsonwebtoken.Claims;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@Service
//@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private IdWorker idWorker;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderGoodsMapper orderGoodsMapper;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private WebServiceClient webServiceClient;

    /**
     * 实现步骤：
     * 0 生成sn-订单编号
     * 1 解析 token，获取userId
     * 2 获取redis中的数据
     * 3 解析redis中的购物车数据
     * 5 保存订单
     * 6 保存订单商品
     * 7 减少库存
     * 8 返回订单编号
     */
    @Override
    @GlobalTransactional
    public String addOrder(OrderRequest orderRequest, HttpServletRequest request) {
        //1 生成sn
        String sn = idWorker.nextId()+"";

        //2 获取userid
        String token = request.getHeader("authorization");
        Claims claims = JWTUtil.parseToken(token, "admin");
        String userId = claims.get("userId").toString();

        //3 获取redis中的信息
        String info = redisTemplate.opsForValue().get(userId);
        //4 解析redis中的数据--转成对象
        List<Cart> list = JSON.parseArray(info, Cart.class);//购物车中存放的是商品信息
        //5 保存订单
        //5.1 准备地址信息，此时我们拥有addressid
        Integer address_id = orderRequest.getAddress_id();
        //5.2 根据addressId去web-service中取出地址信息--feignClient
        Address address = webServiceClient.findAddressByAddressId(address_id);
        //5.3 计算订单总价
        double sum = 0;
        for(Cart c:list){
            if(c.getChecked().equals("true")){
                sum += c.getCount() * c.getPrice();
            }
        }
        //5.4 准备订单数据
        Order order = new Order();
        //订单编号
        order.setSn(sn);
        //收货人信息
        order.setShName(address.getShrName());
        order.setShrMobile(address.getShrMobile());
        order.setShrProvince(address.getShrProvince());
        order.setShrCity(address.getShrCity());
        order.setShrArea(address.getShrArea());
        order.setShrAddress(address.getShrAddress());
        //状态
        order.setStatus(0);
        //用户id
        order.setUserId(userId);
        //总价
        order.setTotalPrice(sum);

        orderMapper.insert(order);

        //6 保存订单商品--打钩的保存
        //打钩的商品集合
        List<Cart> checkedList = new ArrayList<>();

        for(Cart c:list){
            // 只保存打钩的
            if(c.getChecked().equals("true")){
                //打钩的商品添加至checkedList
                checkedList.add(c);

                OrderGoods og = new OrderGoods();
                //订单编号
                og.setSn(sn);
                //spuid

                //skuid
                og.setSkuId(c.getSkuid());
                //购买数量
                og.setNumber(c.getCount());
                //规格信息
                og.setSpecList(c.getSpec_info());
                //skuname
                og.setSkuName(c.getGoods_name());
                //图片地址
                og.setLogo(c.getMidlogo());
                //商品单价
                og.setPrice(c.getPrice());
                //保存商品信息
                orderGoodsMapper.insert(og);

                //7 扣减库存 mysql数据库的库存
                webServiceClient.updateSkuCount(c.getSkuid(),c.getCount());
            }
        }

        // 更新redis中的数据--下过订单的商品 从redis中移除
        list.removeAll(checkedList);
        //将list重新放入redis
        redisTemplate.opsForValue().set(userId,JSON.toJSONString(list));

        //8 返回sn
        return sn;
    }

    @Override
    public void updateStatus(String sn, int status) {
        orderMapper.updateOrderStatus(sn,status);
    }
}
